module Lan_1 where

import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.List

symbols_1 =
  zip names sets
  where
    names = map (:[]) ['A', 'B'..'Z']
    sets = map S.fromList 
      [(['a', 'b'..'z'] ++ ['A', 'B'..'Z']) Data.List.\\ "eE"
      , " \t\r\n"
      , ['0','1'..'9']
      , "=*()"
      , "eE"
      , "+"
      , "."
      , "-"
      ]

s_q = "q0"
eos = "END"

delta_1 = M.fromList
  [
      (("q0", "A"), ("q1", [a0]))
    , (("q0", "B"), ("q0", [a1]))
    , (("q0", "C"), ("q2", [a0]))
    , (("q0", "D"), ("q0", [a1, a2]))
    , (("q0", "E"), ("q1", [a0]))
    , (("q0", "F"), ("q0", [a1, a2]))
    , (("q0", eos), ("HALT", []))

    , (("q1", "A"), ("q1", [a0]))
    , (("q1", "B"), ("q0", [a1]))
    , (("q1", "C"), ("q1", [a0]))
    , (("q1", "D"), ("q0", [a1, a2]))
    , (("q1", "E"), ("q1", [a0]))
    , (("q1", "F"), ("q0", [a1, a2]))
    , (("q1", eos), ("HALT", [a1]))

    , (("q2", "B"), ("q0", [a1]))
    , (("q2", "C"), ("q2", [a0]))
    , (("q2", "D"), ("q0", [a1, a2]))
    , (("q2", "E"), ("q4", [a0]))
    , (("q2", "F"), ("q0", [a1, a2]))
    , (("q2", "G"), ("q3", [a0]))
    , (("q2", eos), ("HALT", [a1]))

    , (("q3", "C"), ("q5", [a0]))

    , (("q4", "F"), ("q6", [a0]))
    , (("q4", "H"), ("q6", [a0]))

    , (("q5", "B"), ("q0", [a1]))
    , (("q5", "C"), ("q5", [a0]))
    , (("q5", "D"), ("q0", [a1, a2]))
    , (("q5", "E"), ("q4", [a0]))
    , (("q5", "F"), ("q0", [a1, a2]))
    , (("q5", eos), ("HALT", [a1]))

    , (("q6", "C"), ("q7", [a0]))

    , (("q7", "B"), ("q0", [a1]))
    , (("q7", "C"), ("q7", [a0]))
    , (("q7", "D"), ("q0", [a1, a2]))
    , (("q7", "F"), ("q0", [a1, a2]))
    , (("q7", eos), ("HALT", [a1]))
  ]

actions = [a0, a1, a2]

str = "ADD = BDD + 1.12e-10"

type Lexeme = (String, String)
type Action = (Char, String, [Lexeme]) -> (Char, String, [Lexeme]) 

a0 :: Action 
a0 (ch, buf, lexs) = (ch, buf ++ [ch], lexs)

a1 :: Action 
a1 (ch, buf, lexs) 
  | buf == [] = (ch, buf, lexs)
  | otherwise = (ch, [], lexs ++ [("ID", buf)])

a2 :: Action 
a2 (ch, buf, lex) = (ch, buf, lex ++ [(name, [ch])])
  where 
    name = case ch of
      '=' -> "A_OP"
      '(' -> "B"
      ')' -> "CB"
      otherwise -> "OP"
